home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 1 / The Arsenal Files (Arsenal Computer).ISO / archive / unixarc.pt3 < prev    next >
Internet Message Format  |  1994-01-23  |  64KB

  1. From pacbell!ames!mailrus!cornell!rochester!bbn!bbn.com!rsalz Fri Jul  1 13:11:39 1988
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v15i079:  ARC (PC compression program), v5.21, Part03/05
  5. Message-ID: <967@fig.bbn.com>
  6. Date: 1 Jul 88 20:11:39 GMT
  7.  
  8. Submitted-by: hyc@math.lsa.umich.edu
  9. Posting-number: Volume 15, Issue 79
  10. Archive-name: arc5.21/part03
  11.  
  12. #--------------------------------CUT HERE-------------------------------------
  13. #! /bin/sh
  14. #
  15. # This is a shell archive.  Save this into a file, edit it
  16. # and delete all lines above this comment.  Then give this
  17. # file to sh by executing the command "sh file".  The files
  18. # will be extracted into the current directory owned by
  19. # you with default permissions.
  20. #
  21. # The files contained herein are:
  22. #
  23. # -rw-r--r--  1 hyc         11146 Jun 17 17:03 arc.c
  24. # -rw-r--r--  1 hyc          3318 Jun  1 19:59 arc.h
  25. # -rw-r--r--  1 hyc          9286 Jun 13 00:31 arcadd.c
  26. # -rw-r--r--  1 hyc          1204 Jun  1 15:16 arccode.c
  27. # -rw-r--r--  1 hyc          3396 Jun  1 19:18 arccvt.c
  28. # -rw-r--r--  1 hyc          2070 Jun 13 04:26 arcdata.c
  29. # -rw-r--r--  1 hyc          2055 Apr 19 01:39 arcdel.c
  30. # -rw-r--r--  1 hyc          5008 Jun 13 14:08 arcdos.c
  31. # -rw-r--r--  1 hyc          4898 Jun 13 14:06 arcext.c
  32. # -rw-r--r--  1 hyc          7418 Jun 13 13:48 arcio.c
  33. # -rw-r--r--  1 hyc          4418 Jun  1 18:06 arclst.c
  34. #
  35. echo 'x - arc.c'
  36. if test -f arc.c; then echo 'shar: not overwriting arc.c'; else
  37. sed 's/^X//' << '________This_Is_The_END________' > arc.c
  38. X/*
  39. X * $Header: arc.c,v 1.10 88/06/17 15:22:48 hyc Locked $
  40. X */
  41. X
  42. X/*  ARC - Archive utility
  43. X  
  44. X    Version 5.21, created on 04/22/87 at 15:05:21
  45. X  
  46. X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  47. X  
  48. X    By:     Thom Henderson
  49. X  
  50. X    Description:
  51. X     This program is a general archive utility, and is used to maintain
  52. X     an archive of files.  An "archive" is a single file that combines
  53. X     many files, reducing storage space and allowing multiple files to
  54. X     be handled as one.
  55. X  
  56. X    Instructions:
  57. X     Run this program with no arguments for complete instructions.
  58. X  
  59. X    Programming notes:
  60. X     ARC Version 2 differs from version 1 in that archive entries
  61. X     are automatically compressed when they are added to the archive,
  62. X     making a separate compression step unecessary.     The nature of the
  63. X     compression is indicated by the header version number placed in
  64. X     each archive entry, as follows:
  65. X  
  66. X     1 = Old style, no compression
  67. X     2 = New style, no compression
  68. X     3 = Compression of repeated characters only
  69. X     4 = Compression of repeated characters plus Huffman SQueezing
  70. X     5 = Lempel-Zev packing of repeated strings (old style)
  71. X     6 = Lempel-Zev packing of repeated strings (new style)
  72. X     7 = Lempel-Zev Williams packing with improved hash function
  73. X     8 = Dynamic Lempel-Zev packing with adaptive reset
  74. X     9 = Dynamic Lempel-Zev packing, larger hash table
  75. X  
  76. X     Type 5, Lempel-Zev packing, was added as of version 4.0
  77. X  
  78. X     Type 6 is Lempel-Zev packing where runs of repeated characters
  79. X     have been collapsed, and was added as of version 4.1
  80. X  
  81. X     Type 7 is a variation of Lempel-Zev using a different hash
  82. X     function which yields speed improvements of 20-25%, and was
  83. X     added as of version 4.6
  84. X  
  85. X     Type 8 is a different implementation of Lempel-Zev, using a
  86. X     variable code size and an adaptive block reset, and was added
  87. X     as of version 5.0
  88. X  
  89. X     Type 9 is a slight modification of type 8, first used by Phil
  90. X     Katz in his PKARC utilites. The primary difference is the use
  91. X     of a hash table twice as large as for type 8, and that this
  92. X     algorithm called Squashing, doesn't perform run-length encoding
  93. X     on the input data.
  94. X  
  95. X     Verion 4.3 introduced a temporary file for holding the result
  96. X     of the first crunch pass, thus speeding up crunching.
  97. X  
  98. X     Version 4.4 introduced the ARCTEMP environment string, so that
  99. X     the temporary crunch file may be placed on a ramdisk.    Also
  100. X     added was the distinction bewteen Adding a file in all cases,
  101. X     and Updating a file only if the disk file is newer than the
  102. X     corresponding archive entry.
  103. X  
  104. X     The compression method to use is determined when the file is
  105. X     added, based on whichever method yields the smallest result.
  106. X  
  107. X    Language:
  108. X     Computer Innovations Optimizing C86
  109. X*/
  110. X#include <stdio.h>
  111. X#include "arc.h"
  112. X
  113. Xint        strlen();
  114. Xvoid        addarc(), delarc(), extarc(), lstarc(), tstarc(), cvtarc(), runarc();
  115. Xvoid        abort();
  116. X#if    MTS
  117. Xvoid        etoa();
  118. X#endif
  119. X#if    GEMDOS
  120. Xlong        _stksize = 24576;
  121. X#endif
  122. Xchar        *strcpy(), *strcat();
  123. X
  124. Xstatic char   **lst;        /* files list */
  125. Xstatic int    lnum;        /* length of files list */
  126. X
  127. Xmain(num, arg)            /* system entry point */
  128. X    int        num;    /* number of arguments */
  129. X    char           *arg[];    /* pointers to arguments */
  130. X{
  131. X    char        opt = 0;/* selected action */
  132. X    char           *a;    /* option pointer */
  133. X    char           *makefnam();    /* filename fixup routine */
  134. X    void        upper();/* case conversion routine */
  135. X    char           *index();/* string index utility */
  136. X    char           *envfind();    /* environment searcher */
  137. X    int        n;    /* index */
  138. X    char           *arctemp2, *calloc(), *mktemp();
  139. X#if    GEMDOS
  140. X    void        exitpause();
  141. X#endif
  142. X#if    MTS
  143. X    fortran void    guinfo();
  144. X    char        gotinf[4];
  145. X#endif
  146. X
  147. X    if (num < 3) {
  148. X        printf("ARC - Archive utility, Version 5.21, created on 04/22/87 at 15:05:21\n");
  149. X/*        printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;");
  150. X        printf(" ALL RIGHTS RESERVED\n\n");
  151. X        printf("Please refer all inquiries to:\n\n");
  152. X        printf("       System Enhancement Associates\n");
  153. X        printf("       21 New Street, Wayne NJ 07470\n\n");
  154. X        printf("You may copy and distribute this program freely,");
  155. X        printf(" provided that:\n");
  156. X        printf("    1)     No fee is charged for such copying and");
  157. X        printf(" distribution, and\n");
  158. X        printf("    2)     It is distributed ONLY in its original,");
  159. X        printf(" unmodified state.\n\n");
  160. X        printf("If you like this program, and find it of use, then your");
  161. X        printf(" contribution will\n");
  162. X        printf("be appreciated.     You may not use this product in a");
  163. X        printf(" commercial environment\n");
  164. X        printf("or a governmental organization without paying a license");
  165. X        printf(" fee of $35.  Site\n");
  166. X        printf("licenses and commercial distribution licenses are");
  167. X        printf(" available.  A program\n");
  168. X        printf("disk and printed documentation are available for $50.\n");
  169. X        printf("\nIf you fail to abide by the terms of this license, ");
  170. X        printf(" then your conscience\n");
  171. X        printf("will haunt you for the rest of your life.\n\n"); */
  172. X#if    MSDOS
  173. X        printf("Usage: ARC {amufdxerplvtc}[bswnoq][g<password>]");
  174. X#endif
  175. X#if    GEMDOS
  176. X        printf("Usage: ARC {amufdxerplvtc}[bhswnoq][g<password>]");
  177. X#endif
  178. X#if    UNIX
  179. X        printf("Usage: arc {amufdxerplvtc}[biswnoq][g<password>]");
  180. X#endif
  181. X#if    MTS
  182. X        printf("Parameters: {amufdxeplvtc}[biswnoq][g<password>]");
  183. X#endif
  184. X        printf(" <archive> [<filename> . . .]\n");
  185. X        printf("Where:     a   = add files to archive\n");
  186. X        printf("     m   = move files to archive\n");
  187. X        printf("     u   = update files in archive\n");
  188. X        printf("     f   = freshen files in archive\n");
  189. X        printf("     d   = delete files from archive\n");
  190. X        printf("     x,e = extract files from archive\n");
  191. X#if    !MTS
  192. X        printf("     r   = run files from archive\n");
  193. X#endif
  194. X        printf("     p   = copy files from archive to");
  195. X        printf(" standard output\n");
  196. X        printf("     l   = list files in archive\n");
  197. X        printf("     v   = verbose listing of files in archive\n");
  198. X        printf("     t   = test archive integrity\n");
  199. X        printf("     c   = convert entry to new packing method\n");
  200. X        printf("     b   = retain backup copy of archive\n");
  201. X#if    GEMDOS
  202. X        printf("     h   = hold screen after finishing\n");
  203. X#endif
  204. X#if    MTS
  205. X        printf("     i   = suppress ASCII/EBCDIC translation\n");
  206. X#endif
  207. X#if    UNIX
  208. X        printf("     i   = suppress image mode (translate EOL)\n");
  209. X#endif
  210. X        printf("     s   = suppress compression (store only)\n");
  211. X        printf("     w   = suppress warning messages\n");
  212. X        printf("     n   = suppress notes and comments\n");
  213. X        printf("     o   = overwrite existing files when");
  214. X        printf(" extracting\n");
  215. X        printf("     q   = squash instead of crunching\n");
  216. X        printf("     g   = Encrypt/decrypt archive entry\n");
  217. X        printf("\nAdapted from MSDOS by Howard Chu\n");
  218. X        /*
  219. X         * printf("\nPlease refer to the program documentation for");
  220. X         * printf(" complete instructions.\n"); 
  221. X         */
  222. X#if    GEMDOS
  223. X        exitpause();
  224. X#endif
  225. X        return 1;
  226. X    }
  227. X    /* see where temp files go */
  228. X#if    !MTS
  229. X    arctemp = calloc(1, STRLEN);
  230. X    if (!(arctemp2 = envfind("ARCTEMP")))
  231. X        arctemp2 = envfind("TMPDIR");
  232. X    if (arctemp2) {
  233. X        strcpy(arctemp, arctemp2);
  234. X        n = strlen(arctemp);
  235. X        if (arctemp[n - 1] != CUTOFF)
  236. X            arctemp[n] = CUTOFF;
  237. X    }
  238. X#if    !MSDOS
  239. X    strcat(arctemp, mktemp("AXXXXXX"));
  240. X#else
  241. X    strcat(arctemp, "$ARCTEMP");
  242. X#endif
  243. X#else
  244. X    guinfo("SHFSEP    ", gotinf);
  245. X    sepchr[0] = gotinf[0];
  246. X    guinfo("SCRFCHAR", gotinf);
  247. X    tmpchr[0] = gotinf[0];
  248. X    arctemp = "-$$$";
  249. X    arctemp[0] = tmpchr[0];
  250. X#endif
  251. X
  252. X#if    !UNIX
  253. X    /* avoid any case problems with arguments */
  254. X
  255. X    for (n = 1; n < num; n++)    /* for each argument */
  256. X        upper(arg[n]);    /* convert it to uppercase */
  257. X#else
  258. X    /* avoid case problems with command options */
  259. X    upper(arg[1]);        /* convert to uppercase */
  260. X#endif
  261. X
  262. X    /* create archive names, supplying defaults */
  263. X    makefnam(arg[2], ".arc", arcname);
  264. X    /* makefnam(".$$$",arcname,newname); */
  265. X    sprintf(newname, "%s.arc", arctemp);
  266. X    makefnam(".BAK", arcname, bakname);
  267. X
  268. X    /* now scan the command and see what we are to do */
  269. X
  270. X    for (a = arg[1]; *a; a++) {    /* scan the option flags */
  271. X#if    !MTS
  272. X        if (index("AMUFDXEPLVTCR", *a)) {    /* if a known command */
  273. X#else
  274. X        if (index("AMUFDXEPLVTC", *a)) {
  275. X#endif
  276. X            if (opt)/* do we have one yet? */
  277. X                abort("Cannot mix %c and %c", opt, *a);
  278. X            opt = *a;    /* else remember it */
  279. X        } else if (*a == 'B')    /* retain backup copy */
  280. X            keepbak = 1;
  281. X
  282. X        else if (*a == 'W')    /* suppress warnings */
  283. X            warn = 0;
  284. X#if    !DOS
  285. X        else if (*a == 'I')    /* image mode, no ASCII/EBCDIC x-late */
  286. X            image = !image;
  287. X#endif
  288. X#if    GEMDOS
  289. X        else if (*a == 'H')    /* pause before exit */
  290. X            hold = 1;
  291. X#endif
  292. X
  293. X        else if (*a == 'N')    /* suppress notes and comments */
  294. X            note = 0;
  295. X
  296. X        else if (*a == 'O')    /* overwrite file on extract */
  297. X            overlay = 1;
  298. X
  299. X        else if (*a == 'G') {    /* garble */
  300. X            password = a + 1;
  301. X            while (*a)
  302. X                a++;
  303. X            a--;
  304. X#if    MTS
  305. X            etoa(password, strlen(password));
  306. X#endif
  307. X        } else if (*a == 'S')    /* storage kludge */
  308. X            nocomp = 1;
  309. X
  310. X        else if (*a == 'K')    /* special kludge */
  311. X            kludge = 1;
  312. X
  313. X        else if (*a == 'Q')    /* use squashing */
  314. X            dosquash = 1;
  315. X
  316. X        else if (*a == '-' || *a == '/')    /* UNIX and PC-DOS
  317. X                             * option markers */
  318. X            ;
  319. X
  320. X        else
  321. X            abort("%c is an unknown command", *a);
  322. X    }
  323. X
  324. X    if (!opt)
  325. X        abort("I have nothing to do!");
  326. X
  327. X    /* get the files list set up */
  328. X
  329. X    lnum = num - 3;        /* initial length of list */
  330. X    lst = (char **) calloc((lnum==0) ? 1:lnum,
  331. X                 sizeof(char *));    /* initial list */
  332. X    for (n = 3; n < num; n++)
  333. X        lst[n - 3] = arg[n];
  334. X
  335. X    for (n = 0; n < lnum;) {/* expand indirect references */
  336. X        if (*lst[n] == '@')
  337. X            expandlst(n);
  338. X        else
  339. X            n++;
  340. X    }
  341. X
  342. X    /* act on whatever action command was given */
  343. X
  344. X    switch (opt) {        /* action depends on command */
  345. X    case 'A':        /* Add */
  346. X    case 'M':        /* Move */
  347. X    case 'U':        /* Update */
  348. X    case 'F':        /* Freshen */
  349. X        addarc(lnum, lst, (opt == 'M'), (opt == 'U'), (opt == 'F'));
  350. X        break;
  351. X
  352. X    case 'D':        /* Delete */
  353. X        delarc(lnum, lst);
  354. X        break;
  355. X
  356. X    case 'E':        /* Extract */
  357. X    case 'X':        /* eXtract */
  358. X    case 'P':        /* Print */
  359. X        extarc(lnum, lst, (opt == 'P'));
  360. X        break;
  361. X
  362. X    case 'V':        /* Verbose list */
  363. X        bose = 1;
  364. X    case 'L':        /* List */
  365. X        lstarc(lnum, lst);
  366. X        break;
  367. X
  368. X    case 'T':        /* Test */
  369. X        tstarc();
  370. X        break;
  371. X
  372. X    case 'C':        /* Convert */
  373. X        cvtarc(lnum, lst);
  374. X        break;
  375. X#if    !MTS
  376. X    case 'R':        /* Run */
  377. X        runarc(lnum, lst);
  378. X        break;
  379. X#endif
  380. X    default:
  381. X        abort("I don't know how to do %c yet!", opt);
  382. X    }
  383. X#if    GEMDOS
  384. X    if (hold)
  385. X        exitpause();
  386. X#endif
  387. X    return nerrs;
  388. X}
  389. Xstatic
  390. Xexpandlst(n)            /* expand an indirect reference */
  391. X    int        n;    /* number of entry to expand */
  392. X{
  393. X    FILE           *lf, *fopen();    /* list file, opener */
  394. X    char           *malloc(), *realloc();    /* memory managers */
  395. X    char        buf[100];    /* input buffer */
  396. X    int        x;    /* index */
  397. X    char           *p = lst[n] + 1; /* filename pointer */
  398. X
  399. X    if (*p) {        /* use name if one was given */
  400. X        makefnam(p, ".CMD", buf);
  401. X        if (!(lf = fopen(buf, "r")))
  402. X            abort("Cannot read list of files in %s", buf);
  403. X    } else
  404. X        lf = stdin;    /* else use standard input */
  405. X
  406. X    for (x = n + 1; x < lnum; x++)    /* drop reference from the list */
  407. X        lst[x - 1] = lst[x];
  408. X    lnum--;
  409. X
  410. X    while (fscanf(lf, "%99s", buf) > 0) {    /* read in the list */
  411. X        if (!(lst =(char **)realloc(lst, (lnum + 1) * sizeof(char *))))
  412. X            abort("too many file references");
  413. X
  414. X        lst[lnum] = malloc(strlen(buf) + 1);
  415. X        strcpy(lst[lnum], buf); /* save the name */
  416. X        lnum++;
  417. X    }
  418. X
  419. X    if (lf != stdin)    /* avoid closing standard input */
  420. X        fclose(lf);
  421. X}
  422. ________This_Is_The_END________
  423. if test `wc -c < arc.c` -ne    11146; then
  424.     echo 'shar: arc.c was damaged during transit (should have been    11146 bytes)'
  425. fi
  426. fi        ; : end of overwriting check
  427. echo 'x - arc.h'
  428. if test -f arc.h; then echo 'shar: not overwriting arc.h'; else
  429. sed 's/^X//' << '________This_Is_The_END________' > arc.h
  430. X/*
  431. X * $Header: arc.h,v 1.7 88/06/01 17:51:06 hyc Locked $
  432. X */
  433. X
  434. X#undef    MSDOS
  435. X#undef    GEMDOS        /* This amusing garbage is to get all my */
  436. X#undef    DOS        /* define's past some compilers, which */
  437. X#undef    BSD        /* apparently define some of these themselves */
  438. X#undef    SYSV
  439. X#undef    UNIX
  440. X#undef    MTS
  441. X
  442. X#define    MSDOS    0        /* MSDOS machine */
  443. X#define    GEMDOS    0        /* Atari, GEMDOS */
  444. X#define    BSD    1        /* BSD4.2 or 4.3 */
  445. X#define    SYSV    0        /* Also uses BSD */
  446. X#define    MTS    0        /* MTS or 370(?) */
  447. X
  448. X/*
  449. X * Assumptions:
  450. X * char = 8 bits
  451. X * short = 16 bits
  452. X * long = 32 bits
  453. X * int >= 16 bits
  454. X */
  455. X
  456. X#if    MSDOS || GEMDOS
  457. X#define    DOS    1
  458. X#define    CUTOFF    '\\'
  459. X#endif
  460. X
  461. X#if    !MSDOS
  462. X#define    envfind    getenv
  463. X#define    setmem(a, b, c)    memset(a, c, b)
  464. X#endif
  465. X
  466. X#if    BSD || SYSV
  467. X#define    UNIX    1
  468. X#define    CUTOFF    '/'
  469. X#include <ctype.h>
  470. X#endif
  471. X
  472. X#if    MTS
  473. X#define rindex strrchr
  474. X#define index strchr
  475. X#undef  USEGFINFO        /* define this to use GFINFO for directory */
  476. X#define USECATSCAN        /* scanning, else use CATSCAN/FILEINFO... */
  477. X#define    CUTOFF    sepchr[0]
  478. X#endif
  479. X
  480. X/*  ARC - Archive utility - ARC Header
  481. X  
  482. X    Version 2.17, created on 04/22/87 at 13:09:43
  483. X  
  484. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  485. X  
  486. X    By:     Thom Henderson
  487. X  
  488. X    Description: 
  489. X     This is the header file for the ARC archive utility.  It defines
  490. X     global parameters and the references to the external data.
  491. X  
  492. X  
  493. X    Language:
  494. X     Computer Innovations Optimizing C86
  495. X*/
  496. X
  497. X#define ARCMARK 26        /* special archive marker        */
  498. X#define ARCVER 9        /* archive header version code   */
  499. X#define STRLEN 100        /* system standard string length */
  500. X#define FNLEN 13        /* file name length              */
  501. X#define MAXARG 25        /* maximum number of arguments   */
  502. X
  503. X#ifndef DONT_DEFINE        /* Defined by arcdata.c */
  504. X#include "arcs.h"
  505. X
  506. Xextern int      keepbak;    /* true if saving the old archive */
  507. X#if    !DOS
  508. Xextern int      image;        /* true to suppress CRLF/LF x-late */
  509. X#endif
  510. X#if    MTS
  511. Xextern char     sepchr[2];    /* Shared file separator, default = ':' */
  512. Xextern char     tmpchr[2];    /* Temporary file prefix, default = '-' */
  513. X#endif
  514. X#if    GEMDOS
  515. Xextern int      hold;        /* hold screen before exiting */
  516. X#endif
  517. Xextern int      warn;        /* true to print warnings */
  518. Xextern int      note;        /* true to print comments */
  519. Xextern int      bose;        /* true to be verbose */
  520. Xextern int      nocomp;        /* true to suppress compression */
  521. Xextern int      overlay;    /* true to overlay on extract */
  522. Xextern int      kludge;        /* kludge flag */
  523. Xextern char    *arctemp;    /* arc temp file prefix */
  524. Xextern char    *password;    /* encryption password pointer */
  525. Xextern int      nerrs;        /* number of errors encountered */
  526. Xextern int      changing;    /* true if archive being modified */
  527. X
  528. Xextern char     hdrver;        /* header version */
  529. X
  530. Xextern FILE    *arc;        /* the old archive */
  531. Xextern FILE    *new;        /* the new archive */
  532. Xextern char     arcname[STRLEN];/* storage for archive name */
  533. Xextern char     bakname[STRLEN];/* storage for backup copy name */
  534. Xextern char     newname[STRLEN];/* storage for new archive name */
  535. Xextern unsigned short arcdate;    /* archive date stamp */
  536. Xextern unsigned short arctime;    /* archive time stamp */
  537. Xextern unsigned short olddate;    /* old archive date stamp */
  538. Xextern unsigned short oldtime;    /* old archive time stamp */
  539. Xextern int      dosquash;    /* squash instead of crunch */
  540. X#endif                /* DONT_DEFINE */
  541. ________This_Is_The_END________
  542. if test `wc -c < arc.h` -ne     3318; then
  543.     echo 'shar: arc.h was damaged during transit (should have been     3318 bytes)'
  544. fi
  545. fi        ; : end of overwriting check
  546. echo 'x - arcadd.c'
  547. if test -f arcadd.c; then echo 'shar: not overwriting arcadd.c'; else
  548. sed 's/^X//' << '________This_Is_The_END________' > arcadd.c
  549. X/*
  550. X * $Header: arcadd.c,v 1.8 88/06/13 00:31:15 hyc Locked $
  551. X */
  552. X
  553. X/*
  554. X * ARC - Archive utility - ARCADD
  555. X * 
  556. X * Version 3.40, created on 06/18/86 at 13:10:18
  557. X * 
  558. X * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  559. X * 
  560. X * By:  Thom Henderson
  561. X * 
  562. X * Description: This file contains the routines used to add files to an archive.
  563. X * 
  564. X * Language: Computer Innovations Optimizing C86
  565. X */
  566. X#include <stdio.h>
  567. X#include "arc.h"
  568. X#if    MTS
  569. X#include <mts.h>
  570. X#endif
  571. X
  572. Xstatic    void    addfile();
  573. Xchar    *strcpy();
  574. Xint    strcmp(), strlen(), free(), readhdr(), unlink();
  575. X#if    UNIX
  576. Xint    izadir();
  577. X#endif
  578. Xvoid    writehdr(), filecopy(), getstamp();
  579. Xvoid    pack(), closearc(), openarc(), abort();
  580. X
  581. Xvoid
  582. Xaddarc(num, arg, move, update, fresh)        /* add files to archive */
  583. X    int             num;    /* number of arguments */
  584. X    char           *arg[];    /* pointers to arguments */
  585. Xint             move;        /* true if moving file */
  586. Xint             update;        /* true if updating */
  587. Xint             fresh;        /* true if freshening */
  588. X{
  589. X    char           *d, *dir();    /* directory junk */
  590. X    char            buf[STRLEN];    /* pathname buffer */
  591. X    char          **path;    /* pointer to pointers to paths */
  592. X    char          **name;    /* pointer to pointers to names */
  593. X    int             nfiles = 0;    /* number of files in lists */
  594. X    int             notemp;    /* true until a template works */
  595. X    int             nowork = 1;    /* true until files are added */
  596. X    char           *i, *rindex();    /* string indexing junk */
  597. X    char           *malloc(), *realloc();    /* memory allocators */
  598. X    int             n;    /* index */
  599. X#if    MSDOS
  600. X    unsigned int    coreleft();    /* remaining memory reporter */
  601. X#endif
  602. X    int        addbunch();
  603. X
  604. X    if (num < 1) {        /* if no files named */
  605. X        num = 1;    /* then fake one */
  606. X#if    DOS
  607. X        arg[0] = "*.*";    /* add everything */
  608. X#endif
  609. X#if    UNIX
  610. X        arg[0] = "*";
  611. X#endif
  612. X#if    MTS
  613. X        arg[0] = "?";
  614. X#endif
  615. X    }
  616. X    path = (char **) malloc(sizeof(char **));
  617. X    name = (char **) malloc(sizeof(char **));
  618. X
  619. X
  620. X    for (n = 0; n < num; n++) {    /* for each template supplied */
  621. X        strcpy(buf, arg[n]);    /* get ready to fix path */
  622. X#if    !MTS
  623. X        if (!(i = rindex(buf, '\\')))
  624. X            if (!(i = rindex(buf, '/')))
  625. X                if (!(i = rindex(buf, ':')))
  626. X                    i = buf - 1;
  627. X#else
  628. X        if (!(i = rindex(buf, sepchr[0])))
  629. X            if (buf[0] != tmpchr[0])
  630. X                i = buf - 1;
  631. X            else
  632. X                i = buf;
  633. X#endif
  634. X        i++;        /* pointer to where name goes */
  635. X
  636. X        notemp = 1;    /* reset files flag */
  637. X        for (d = dir(arg[n]); d; d = dir(NULL)) {
  638. X            notemp = 0;    /* template is giving results */
  639. X            nfiles++;    /* add each matching file */
  640. X            path = (char **) realloc(path, nfiles * sizeof(char **));
  641. X            name = (char **) realloc(name, nfiles * sizeof(char **));
  642. X            strcpy(i, d);    /* put name in path */
  643. X            path[nfiles - 1] = malloc(strlen(buf) + 1);
  644. X            strcpy(path[nfiles - 1], buf);
  645. X            name[nfiles - 1] = d;    /* save name */
  646. X#if    MSDOS
  647. X            if (coreleft() < 5120) {
  648. X                nfiles = addbunch(nfiles, path, name, move, update, fresh);
  649. X                nowork = nowork && !nfiles;
  650. X                while (nfiles) {
  651. X                    free(path[--nfiles]);
  652. X                    free(name[nfiles]);
  653. X                }
  654. X                free(path);
  655. X                free(name);
  656. X                path = name = NULL;
  657. X            }
  658. X#endif
  659. X        }
  660. X        if (notemp && warn)
  661. X            printf("No files match: %s\n", arg[n]);
  662. X    }
  663. X
  664. X    if (nfiles) {
  665. X        nfiles = addbunch(nfiles, path, name, move, update, fresh);
  666. X        nowork = nowork && !nfiles;
  667. X        while (nfiles) {
  668. X            free(path[--nfiles]);
  669. X            free(name[nfiles]);
  670. X        }
  671. X        free(path);
  672. X        free(name);
  673. X    }
  674. X    if (nowork && warn)
  675. X        printf("No files were added.\n");
  676. X}
  677. X
  678. Xint
  679. Xaddbunch(nfiles, path, name, move, update, fresh)    /* add a bunch of files */
  680. X    int             nfiles;    /* number of files to add */
  681. X    char          **path;    /* pointers to pathnames */
  682. X    char          **name;    /* pointers to filenames */
  683. X    int             move;    /* true if moving file */
  684. X    int             update;    /* true if updating */
  685. X    int             fresh;    /* true if freshening */
  686. X{
  687. X    int             m, n;    /* indices */
  688. X    char           *d;    /* swap pointer */
  689. X    struct heads    hdr;    /* file header data storage */
  690. X
  691. X    for (n = 0; n < nfiles - 1; n++) {    /* sort the list of names */
  692. X        for (m = n + 1; m < nfiles; m++) {
  693. X            if (strcmp(name[n], name[m]) > 0) {
  694. X                d = path[n];
  695. X                path[n] = path[m];
  696. X                path[m] = d;
  697. X                d = name[n];
  698. X                name[n] = name[m];
  699. X                name[m] = d;
  700. X            }
  701. X        }
  702. X    }
  703. X
  704. X    for (n = 0; n < nfiles - 1;) {    /* consolidate the list of names */
  705. X        if (!strcmp(path[n], path[n + 1])    /* if duplicate names */
  706. X            ||!strcmp(path[n], arcname)    /* or this archive */
  707. X#if    UNIX
  708. X            ||izadir(path[n])    /* or a directory */
  709. X#endif
  710. X            ||!strcmp(path[n], newname)    /* or the new version */
  711. X            ||!strcmp(path[n], bakname)) {    /* or its backup */
  712. X            free(path[n]);    /* then forget the file */
  713. X            free(name[n]);
  714. X            for (m = n; m < nfiles - 1; m++) {
  715. X                path[m] = path[m + 1];
  716. X                name[m] = name[m + 1];
  717. X            }
  718. X            nfiles--;
  719. X        } else
  720. X            n++;    /* else test the next one */
  721. X    }
  722. X
  723. X    if (!strcmp(path[n], arcname)    /* special check for last file */
  724. X        ||!strcmp(path[n], newname)    /* courtesy of Rick Moore */
  725. X#if    UNIX
  726. X        ||izadir(path[n])
  727. X#endif
  728. X        || !strcmp(path[n], bakname)) {
  729. X        free(path[n]);
  730. X        free(name[n]);
  731. X        nfiles--;
  732. X    }
  733. X    if (!nfiles)        /* make sure we got some */
  734. X        return 0;
  735. X
  736. X    for (n = 0; n < nfiles - 1; n++) {    /* watch out for duplicate
  737. X                         * names */
  738. X        if (!strcmp(name[n], name[n + 1]))
  739. X            abort("Duplicate filenames:\n  %s\n  %s", path[n], path[n + 1]);
  740. X    }
  741. X    openarc(1);        /* open archive for changes */
  742. X
  743. X    for (n = 0; n < nfiles; n++)    /* add each file in the list */
  744. X        addfile(path[n], name[n], update, fresh);
  745. X
  746. X    /* now we must copy over all files that follow our additions */
  747. X
  748. X    while (readhdr(&hdr, arc)) {    /* while more entries to copy */
  749. X        writehdr(&hdr, new);
  750. X        filecopy(arc, new, hdr.size);
  751. X    }
  752. X    hdrver = 0;        /* archive EOF type */
  753. X    writehdr(&hdr, new);    /* write out our end marker */
  754. X    closearc(1);        /* close archive after changes */
  755. X
  756. X    if (move) {        /* if this was a move */
  757. X        for (n = 0; n < nfiles; n++) {    /* then delete each file
  758. X                         * added */
  759. X            if (unlink(path[n]) && warn) {
  760. X                printf("Cannot unsave %s\n", path[n]);
  761. X                nerrs++;
  762. X            }
  763. X        }
  764. X    }
  765. X    return nfiles;        /* say how many were added */
  766. X}
  767. X
  768. Xstatic          void
  769. Xaddfile(path, name, update, fresh)    /* add named file to archive */
  770. X    char           *path;    /* path name of file to add */
  771. X    char           *name;    /* name of file to add */
  772. X    int             update;    /* true if updating */
  773. X    int             fresh;    /* true if freshening */
  774. X{
  775. X    struct heads    nhdr;    /* data regarding the new file */
  776. X    struct heads    ohdr;    /* data regarding an old file */
  777. X    FILE           *f, *fopen();    /* file to add, opener */
  778. X    long            starts, ftell();    /* file locations */
  779. X    int             upd = 0;/* true if replacing an entry */
  780. X
  781. X#if    !MTS
  782. X    if (!(f = fopen(path, "rb")))
  783. X#else
  784. X    if (image)
  785. X        f = fopen(path, "rb");
  786. X    else
  787. X        f = fopen(path, "r");
  788. X    if (!f)
  789. X#endif
  790. X    {
  791. X        if (warn) {
  792. X            printf("Cannot read file: %s\n", path);
  793. X            nerrs++;
  794. X        }
  795. X        return;
  796. X    }
  797. X    strcpy(nhdr.name, name);/* save name */
  798. X    nhdr.size = 0;        /* clear out size storage */
  799. X    nhdr.crc = 0;        /* clear out CRC check storage */
  800. X#if    !MTS
  801. X    getstamp(f, &nhdr.date, &nhdr.time);
  802. X#else
  803. X    {
  804. X    char *buffer, *malloc();
  805. X    int    inlen;
  806. X    struct    GDDSECT    *region;
  807. X
  808. X    region=gdinfo(f->_fd);
  809. X    inlen=region->GDINLEN;
  810. X    buffer=malloc(inlen);   /* maximum line length */
  811. X    setbuf(f,buffer);        
  812. X    f->_bufsiz=inlen;        
  813. X    f->_mods|=0x00040000;   /* Don't do "$continue with" */
  814. X    f->_mods&=0xfff7ffff;   /* turn it off, if set... */
  815. X    }
  816. X    getstamp(path, &nhdr.date, &nhdr.time);
  817. X#endif
  818. X
  819. X    /* position archive to spot for new file */
  820. X
  821. X    if (arc) {        /* if adding to existing archive */
  822. X        starts = ftell(arc);    /* where are we? */
  823. X        while (readhdr(&ohdr, arc)) {    /* while more files to check */
  824. X            if (!strcmp(ohdr.name, nhdr.name)) {
  825. X                upd = 1;    /* replace existing entry */
  826. X                if (update || fresh) {    /* if updating or
  827. X                             * freshening */
  828. X                    if (nhdr.date < ohdr.date
  829. X                        || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) {
  830. X                        fseek(arc, starts, 0);
  831. X                        fclose(f);
  832. X                        return;    /* skip if not newer */
  833. X                    }
  834. X                }
  835. X            }
  836. X            if (strcmp(ohdr.name, nhdr.name) >= 0)
  837. X                break;    /* found our spot */
  838. X
  839. X            writehdr(&ohdr, new);    /* entry preceeds update;
  840. X                         * keep it */
  841. X            filecopy(arc, new, ohdr.size);
  842. X            starts = ftell(arc);    /* now where are we? */
  843. X        }
  844. X
  845. X        if (upd) {    /* if an update */
  846. X            if (note) {
  847. X                printf("Updating file: %-12s  ", name);
  848. X                fflush(stdout);
  849. X            }
  850. X            fseek(arc, ohdr.size, 1);
  851. X        } else if (fresh) {    /* else if freshening */
  852. X            fseek(arc, starts, 0);    /* then do not add files */
  853. X            fclose(f);
  854. X            return;
  855. X        } else {    /* else adding a new file */
  856. X            if (note) {
  857. X                printf("Adding file:   %-12s  ", name);
  858. X                fflush(stdout);
  859. X            }
  860. X            fseek(arc, starts, 0);    /* reset for next time */
  861. X        }
  862. X    } else {        /* no existing archive */
  863. X        if (fresh) {    /* cannot freshen nothing */
  864. X            fclose(f);
  865. X            return;
  866. X        } else if (note) {    /* else adding a file */
  867. X            printf("Adding file:   %-12s  ", name);
  868. X            fflush(stdout);
  869. X        }
  870. X    }
  871. X
  872. X    starts = ftell(new);    /* note where header goes */
  873. X    hdrver = ARCVER;        /* anything but end marker */
  874. X    writehdr(&nhdr, new);    /* write out header skeleton */
  875. X    pack(f, new, &nhdr);    /* pack file into archive */
  876. X    strcpy(nhdr.name, name);
  877. X    fseek(new, starts, 0);    /* move back to header skeleton */
  878. X    writehdr(&nhdr, new);    /* write out real header */
  879. X    fseek(new, nhdr.size, 1);    /* skip over data to next header */
  880. X    fclose(f);        /* all done with the file */
  881. X}
  882. ________This_Is_The_END________
  883. if test `wc -c < arcadd.c` -ne     9286; then
  884.     echo 'shar: arcadd.c was damaged during transit (should have been     9286 bytes)'
  885. fi
  886. fi        ; : end of overwriting check
  887. echo 'x - arccode.c'
  888. if test -f arccode.c; then echo 'shar: not overwriting arccode.c'; else
  889. sed 's/^X//' << '________This_Is_The_END________' > arccode.c
  890. X/*
  891. X * $Header: arccode.c,v 1.1 88/06/01 15:15:58 hyc Locked $
  892. X */
  893. X
  894. X/*
  895. X * ARC - Archive utility - ARCCODE
  896. X * 
  897. X * Version 1.02, created on 01/20/86 at 13:33:35
  898. X * 
  899. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  900. X * 
  901. X * By:  Thom Henderson
  902. X * 
  903. X * Description: This file contains the routines used to encrypt and decrypt data
  904. X * in an archive.  The encryption method is nothing fancy, being just a
  905. X * routine XOR, but it is used on the packed data, and uses a variable length
  906. X * key.  The end result is something that is in theory crackable, but I'd
  907. X * hate to try it.  It should be more than sufficient for casual use.
  908. X * 
  909. X * Language: Computer Innovations Optimizing C86
  910. X */
  911. X#include <stdio.h>
  912. X#include "arc.h"
  913. X
  914. Xstatic char    *p;        /* password pointer */
  915. X
  916. Xvoid
  917. Xsetcode()
  918. X{                /* get set for encoding/decoding */
  919. X    p = password;        /* reset password pointer */
  920. X}
  921. X
  922. Xunsigned char
  923. Xcode(c)                /* encode some character */
  924. X    char            c;    /* character to encode */
  925. X{
  926. X    if (p) {        /* if password is in use */
  927. X        if (!*p)    /* if we reached the end */
  928. X            p = password;    /* then wrap back to the start */
  929. X        return c ^ *p++;/* very simple here */
  930. X    } else
  931. X        return c;    /* else no encryption */
  932. X}
  933. ________This_Is_The_END________
  934. if test `wc -c < arccode.c` -ne     1204; then
  935.     echo 'shar: arccode.c was damaged during transit (should have been     1204 bytes)'
  936. fi
  937. fi        ; : end of overwriting check
  938. echo 'x - arccvt.c'
  939. if test -f arccvt.c; then echo 'shar: not overwriting arccvt.c'; else
  940. sed 's/^X//' << '________This_Is_The_END________' > arccvt.c
  941. X/*
  942. X * $Header: arccvt.c,v 1.5 88/06/01 19:17:40 hyc Locked $
  943. X */
  944. X
  945. X/*
  946. X * ARC - Archive utility - ARCCVT
  947. X * 
  948. X * Version 1.16, created on 02/03/86 at 22:53:02
  949. X * 
  950. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  951. X * 
  952. X * By:  Thom Henderson
  953. X * 
  954. X * Description: This file contains the routines used to convert archives to use
  955. X * newer file storage methods.
  956. X * 
  957. X * Language: Computer Innovations Optimizing C86
  958. X */
  959. X#include <stdio.h>
  960. X#include "arc.h"
  961. X
  962. Xvoid    openarc(), rempath(), closearc(), abort(), pack(), writehdr(), filecopy();
  963. Xint    match(), readhdr(), unpack(), unlink();
  964. X
  965. Xstatic char     tempname[STRLEN];    /* temp file name */
  966. X
  967. Xvoid
  968. Xcvtarc(num, arg)        /* convert archive */
  969. X    int             num;    /* number of arguments */
  970. X    char           *arg[];    /* pointers to arguments */
  971. X{
  972. X    struct heads    hdr;    /* file header */
  973. X    int             cvt;    /* true to convert current file */
  974. X    int             did[MAXARG];/* true when argument was used */
  975. X    int             n;    /* index */
  976. X    char           *makefnam();    /* filename fixer */
  977. X    FILE           *fopen();/* file opener */
  978. X    void            cvtfile();
  979. X
  980. X    if (arctemp)        /* use temp area if specified */
  981. X        sprintf(tempname, "%s.CVT", arctemp);
  982. X    else
  983. X        makefnam("$ARCTEMP.CVT", arcname, tempname);
  984. X#if    !DOS
  985. X    image = 1;
  986. X#endif
  987. X
  988. X    openarc(1);        /* open archive for changes */
  989. X
  990. X    for (n = 0; n < num; n++)    /* for each argument */
  991. X        did[n] = 0;    /* reset usage flag */
  992. X    rempath(num, arg);    /* strip off paths */
  993. X
  994. X    if (num) {        /* if files were named */
  995. X        while (readhdr(&hdr, arc)) {    /* while more files to check */
  996. X            cvt = 0;/* reset convert flag */
  997. X            for (n = 0; n < num; n++) {    /* for each template
  998. X                             * given */
  999. X                if (match(hdr.name, arg[n])) {
  1000. X                    cvt = 1;    /* turn on convert flag */
  1001. X                    did[n] = 1;    /* turn on usage flag */
  1002. X                    break;    /* stop looking */
  1003. X                }
  1004. X            }
  1005. X
  1006. X            if (cvt)/* if converting this one */
  1007. X                cvtfile(&hdr);    /* then do it */
  1008. X            else {    /* else just copy it */
  1009. X                writehdr(&hdr, new);
  1010. X                filecopy(arc, new, hdr.size);
  1011. X            }
  1012. X        }
  1013. X    } else
  1014. X        while (readhdr(&hdr, arc))    /* else convert all files */
  1015. X            cvtfile(&hdr);
  1016. X
  1017. X    hdrver = 0;        /* archive EOF type */
  1018. X    writehdr(&hdr, new);    /* write out our end marker */
  1019. X    closearc(1);        /* close archive after changes */
  1020. X
  1021. X    if (note) {
  1022. X        for (n = 0; n < num; n++) {    /* report unused args */
  1023. X            if (!did[n]) {
  1024. X                printf("File not found: %s\n", arg[n]);
  1025. X                nerrs++;
  1026. X            }
  1027. X        }
  1028. X    }
  1029. X}
  1030. X
  1031. Xvoid
  1032. Xcvtfile(hdr)            /* convert a file */
  1033. X    struct heads   *hdr;    /* pointer to header data */
  1034. X{
  1035. X    long            starts, ftell();    /* where the file goes */
  1036. X    FILE           *tmp, *fopen();    /* temporary file */
  1037. X
  1038. X    if (!(tmp = fopen(tempname, "w+b")))
  1039. X        abort("Unable to create temporary file %s", tempname);
  1040. X
  1041. X    if (note) {
  1042. X        printf("Converting file: %-12s   reading, ", hdr->name);
  1043. X        fflush(stdout);
  1044. X    }
  1045. X    unpack(arc, tmp, hdr);    /* unpack the entry */
  1046. X    fseek(tmp, 0L, 0);    /* reset temp for reading */
  1047. X
  1048. X    starts = ftell(new);    /* note where header goes */
  1049. X    hdrver = ARCVER;        /* anything but end marker */
  1050. X    writehdr(hdr, new);    /* write out header skeleton */
  1051. X    pack(tmp, new, hdr);    /* pack file into archive */
  1052. X    fseek(new, starts, 0);    /* move back to header skeleton */
  1053. X    writehdr(hdr, new);    /* write out real header */
  1054. X    fseek(new, hdr->size, 1);    /* skip over data to next header */
  1055. X    fclose(tmp);        /* all done with the file */
  1056. X    if (unlink(tempname) && warn) {
  1057. X        printf("Cannot unsave %s\n", tempname);
  1058. X        nerrs++;
  1059. X    }
  1060. X}
  1061. ________This_Is_The_END________
  1062. if test `wc -c < arccvt.c` -ne     3396; then
  1063.     echo 'shar: arccvt.c was damaged during transit (should have been     3396 bytes)'
  1064. fi
  1065. fi        ; : end of overwriting check
  1066. echo 'x - arcdata.c'
  1067. if test -f arcdata.c; then echo 'shar: not overwriting arcdata.c'; else
  1068. sed 's/^X//' << '________This_Is_The_END________' > arcdata.c
  1069. X/*
  1070. X * $Header: arcdata.c,v 1.6 88/06/01 19:17:58 hyc Locked $
  1071. X */
  1072. X
  1073. X/*  ARC - Archive utility - ARCDATA
  1074. X
  1075. X    Version 2.17, created on 04/22/87 at 13:09:43
  1076. X
  1077. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  1078. X
  1079. X    By:     Thom Henderson
  1080. X
  1081. X    Description: 
  1082. X     This file defines the external data storage used by the ARC
  1083. X     archive utility.
  1084. X
  1085. X
  1086. X    Language:
  1087. X     Computer Innovations Optimizing C86
  1088. X*/
  1089. X#include <stdio.h>
  1090. X
  1091. X#define DONT_DEFINE
  1092. X#include "arc.h"
  1093. X
  1094. Xint             keepbak = 0;    /* true if saving the old archive */
  1095. X#if    UNIX
  1096. Xint        image = 1;    /* true to suppress CRLF/LF x-late */
  1097. X#endif
  1098. X#if    MTS
  1099. Xint             image = 0;    /* true to suppress EBCDIC/ASCII x-late */
  1100. Xchar            sepchr[2] = ":";/* Shared file separator */
  1101. Xchar            tmpchr[2] = "-";/* Temporary file prefix */
  1102. X#endif
  1103. X#if    GEMDOS
  1104. Xint        hold = 0;    /* true to pause before exit */
  1105. X#endif
  1106. Xint             warn = 1;    /* true to print warnings */
  1107. Xint             note = 1;    /* true to print comments */
  1108. Xint             bose = 0;    /* true to be verbose */
  1109. Xint             nocomp = 0;    /* true to suppress compression */
  1110. Xint             overlay = 0;    /* true to overlay on extract */
  1111. Xint             kludge = 0;    /* kludge flag */
  1112. Xchar           *arctemp = NULL;    /* arc temp file prefix */
  1113. Xchar           *password = NULL;/* encryption password pointer */
  1114. Xint             nerrs = 0;    /* number of errors encountered */
  1115. Xint        changing = 0;    /* true if archive being modified */
  1116. X
  1117. Xchar            hdrver;        /* header version */
  1118. X
  1119. XFILE           *arc;        /* the old archive */
  1120. XFILE           *new;        /* the new archive */
  1121. Xchar            arcname[STRLEN];    /* storage for archive name */
  1122. Xchar            bakname[STRLEN];    /* storage for backup copy name */
  1123. Xchar            newname[STRLEN];    /* storage for new archive name */
  1124. Xunsigned short  arcdate = 0;    /* archive date stamp */
  1125. Xunsigned short  arctime = 0;    /* archive time stamp */
  1126. Xunsigned short  olddate = 0;    /* old archive date stamp */
  1127. Xunsigned short  oldtime = 0;    /* old archive time stamp */
  1128. Xint        dosquash = 0;    /* true to squash instead of crunch */
  1129. ________This_Is_The_END________
  1130. if test `wc -c < arcdata.c` -ne     2070; then
  1131.     echo 'shar: arcdata.c was damaged during transit (should have been     2070 bytes)'
  1132. fi
  1133. fi        ; : end of overwriting check
  1134. echo 'x - arcdel.c'
  1135. if test -f arcdel.c; then echo 'shar: not overwriting arcdel.c'; else
  1136. sed 's/^X//' << '________This_Is_The_END________' > arcdel.c
  1137. X/*
  1138. X * $Header: arcdel.c,v 1.3 88/04/19 01:39:32 hyc Exp $
  1139. X */
  1140. X
  1141. X/*
  1142. X * ARC - Archive utility - ARCDEL
  1143. X * 
  1144. X * Version 2.09, created on 02/03/86 at 22:53:27
  1145. X * 
  1146. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1147. X * 
  1148. X * By:  Thom Henderson
  1149. X * 
  1150. X * Description: This file contains the routines used to delete entries in an
  1151. X * archive.
  1152. X * 
  1153. X * Language: Computer Innovations Optimizing C86
  1154. X */
  1155. X#include <stdio.h>
  1156. X#include "arc.h"
  1157. X
  1158. Xvoid    abort(), rempath(), openarc(), closearc(), writehdr(), filecopy();
  1159. Xint    match(), readhdr();
  1160. X
  1161. Xvoid
  1162. Xdelarc(num, arg)        /* remove files from archive */
  1163. X    int             num;    /* number of arguments */
  1164. X    char           *arg[];    /* pointers to arguments */
  1165. X{
  1166. X    struct heads    hdr;    /* header data */
  1167. X    int             del;    /* true to delete a file */
  1168. X    int             did[MAXARG];/* true when argument used */
  1169. X    int             n;    /* index */
  1170. X
  1171. X    if (!num)        /* she must specify which */
  1172. X        abort("You must tell me which files to delete!");
  1173. X
  1174. X    for (n = 0; n < num; n++)    /* for each argument */
  1175. X        did[n] = 0;    /* reset usage flag */
  1176. X    rempath(num, arg);    /* strip off paths */
  1177. X
  1178. X    openarc(1);        /* open archive for changes */
  1179. X
  1180. X    while (readhdr(&hdr, arc)) {    /* while more entries in archive */
  1181. X        del = 0;    /* reset delete flag */
  1182. X        for (n = 0; n < num; n++) {    /* for each template given */
  1183. X            if (match(hdr.name, arg[n])) {
  1184. X                del = 1;    /* turn on delete flag */
  1185. X                did[n] = 1;    /* turn on usage flag */
  1186. X                break;    /* stop looking */
  1187. X            }
  1188. X        }
  1189. X
  1190. X        if (del) {    /* skip over unwanted files */
  1191. X            fseek(arc, hdr.size, 1);
  1192. X            if (note)
  1193. X                printf("Deleting file: %s\n", hdr.name);
  1194. X        } else {    /* else copy over file data */
  1195. X            writehdr(&hdr, new);    /* write out header and file */
  1196. X            filecopy(arc, new, hdr.size);
  1197. X        }
  1198. X    }
  1199. X
  1200. X    hdrver = 0;        /* special end of archive type */
  1201. X    writehdr(&hdr, new);    /* write out archive end marker */
  1202. X    closearc(1);        /* close archive after changes */
  1203. X
  1204. X    if (note) {
  1205. X        for (n = 0; n < num; n++) {    /* report unused arguments */
  1206. X            if (!did[n]) {
  1207. X                printf("File not found: %s\n", arg[n]);
  1208. X                nerrs++;
  1209. X            }
  1210. X        }
  1211. X    }
  1212. X}
  1213. ________This_Is_The_END________
  1214. if test `wc -c < arcdel.c` -ne     2055; then
  1215.     echo 'shar: arcdel.c was damaged during transit (should have been     2055 bytes)'
  1216. fi
  1217. fi        ; : end of overwriting check
  1218. echo 'x - arcdos.c'
  1219. if test -f arcdos.c; then echo 'shar: not overwriting arcdos.c'; else
  1220. sed 's/^X//' << '________This_Is_The_END________' > arcdos.c
  1221. X/*
  1222. X * $Header: arcdos.c,v 1.5 88/06/13 00:40:49 hyc Locked $
  1223. X */
  1224. X
  1225. X/*
  1226. X * ARC - Archive utility - ARCDOS
  1227. X * 
  1228. X * Version 1.44, created on 07/25/86 at 14:17:38
  1229. X * 
  1230. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1231. X * 
  1232. X * By:  Thom Henderson
  1233. X * 
  1234. X * Description: This file contains certain DOS level routines that assist in
  1235. X * doing fancy things with an archive, primarily reading and setting the date
  1236. X * and time last modified.
  1237. X * 
  1238. X * These are, by nature, system dependant functions.  But they are also, by
  1239. X * nature, very expendable.
  1240. X * 
  1241. X * Language: Computer Innovations Optimizing C86
  1242. X */
  1243. X#include <stdio.h>
  1244. X#include "arc.h"
  1245. X
  1246. X#if    MSDOS
  1247. X#include "fileio2.h"        /* needed for filehand */
  1248. X#endif
  1249. X
  1250. X#if    UNIX
  1251. X#include <sys/types.h>
  1252. X#include <sys/stat.h>
  1253. X#include <sys/time.h>
  1254. X#include "tws.h"
  1255. X#endif
  1256. X
  1257. X#if    SYSV
  1258. Xstruct timeval {
  1259. X    long tv_sec;
  1260. X    long tv_usec;
  1261. X};
  1262. X#endif
  1263. X
  1264. X#if    GEMDOS
  1265. X#include <osbind.h>
  1266. X#endif
  1267. X
  1268. Xchar    *strcpy(), *strcat(), *malloc();
  1269. X
  1270. Xvoid
  1271. Xgetstamp(f, date, time)        /* get a file's date/time stamp */
  1272. X#if    !MTS
  1273. X    FILE           *f;    /* file to get stamp from */
  1274. X#else
  1275. X    char           *f;    /* filename "" "" */
  1276. X#endif
  1277. X    unsigned short   *date, *time;    /* storage for the stamp */
  1278. X{
  1279. X#if    MSDOS
  1280. X    struct {
  1281. X        int             ax, bx, cx, dx, si, di, ds, es;
  1282. X    }               reg;
  1283. X
  1284. X    reg.ax = 0x5700;    /* get date/time */
  1285. X    reg.bx = filehand(f);    /* file handle */
  1286. X    if (sysint21(®, ®) & 1)    /* DOS call */
  1287. X        printf("Get timestamp fail (%d)\n", reg.ax);
  1288. X
  1289. X    *date = reg.dx;        /* save date/time */
  1290. X    *time = reg.cx;
  1291. X#endif
  1292. X#if    GEMDOS
  1293. X    int    fd, ret[2];
  1294. X
  1295. X    fd = fileno(f);
  1296. X    Fdatime(ret, fd, 0);
  1297. X    *date = ret[1];
  1298. X    *time = ret[0];
  1299. X#endif
  1300. X#if    UNIX
  1301. X    char           *ctime();
  1302. X    struct stat    *buf;
  1303. X    int             day, hr, min, sec, yr, imon;
  1304. X    static char     mon[4], *mons[12] = {
  1305. X                   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1306. X                    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  1307. X    };
  1308. X
  1309. X    buf = (struct stat *) malloc(sizeof(struct stat));
  1310. X    fstat(fileno(f), buf);
  1311. X
  1312. X    sscanf(ctime(&(buf->st_mtime)), "%*4s%3s%d%d:%d:%d%d", mon, &day, &hr, &min,
  1313. X           &sec, &yr);
  1314. X    for (imon = 0; imon < 12 && strcmp(mon, mons[imon]); imon++);
  1315. X
  1316. X    *date = (unsigned short) (((yr - 1980) << 9) + ((imon + 1) << 5) + day);
  1317. X    *time = (unsigned short) ((hr << 11) + (min << 5) + sec / 2);
  1318. X#endif
  1319. X#if    MTS
  1320. X    fortran         timein(),
  1321. X#if    USEGFINFO
  1322. X                    gfinfo();
  1323. X#else
  1324. X                    fileinfo();
  1325. X#endif
  1326. X    int             stclk[2];
  1327. X    char            name[24];
  1328. X    struct bigtime {
  1329. X        int             greg;
  1330. X        int             year;
  1331. X        int             mon;
  1332. X        int             day;
  1333. X        int             hour;
  1334. X        int             min;
  1335. X        int             sec;
  1336. X        int             usec;
  1337. X        int             week;
  1338. X        int             toff;
  1339. X        int             tzn1;
  1340. X        int             tzn2;
  1341. X    }               tvec;
  1342. X#if    USEGFINFO
  1343. X    static int      gfflag = 0x0009, gfdummy[2] = {
  1344. X                               0, 0
  1345. X    };
  1346. X    int             gfcinfo[18];
  1347. X#else
  1348. X    static int      cattype = 2;
  1349. X#endif
  1350. X
  1351. X    strcpy(name, f);
  1352. X    strcat(name, " ");
  1353. X#if    USEGFINFO
  1354. X    gfcinfo[0] = 18;
  1355. X    gfinfo(name, name, &gfflag, gfcinfo, gfdummy, gfdummy);
  1356. X    timein("*IBM MICROSECONDS*", &gfcinfo[16], &tvec);
  1357. X#else
  1358. X    fileinfo(name, &cattype, "CILCCT  ", stclk);
  1359. X    timein("*IBM MICROSECONDS*", stclk, &tvec);
  1360. X#endif
  1361. X
  1362. X    *date = (unsigned short) (((tvec.year - 1980) << 9) + ((tvec.mon) << 5) + tvec.day);
  1363. X    *time = (unsigned short) ((tvec.hour << 11) + (tvec.min << 5) + tvec.sec / 2);
  1364. X#endif
  1365. X}
  1366. X
  1367. Xvoid
  1368. Xsetstamp(f, date, time)        /* set a file's date/time stamp */
  1369. X    char           *f;    /* filename to stamp */
  1370. X    unsigned short    date, time;    /* desired date, time */
  1371. X{
  1372. X#if    MSDOS
  1373. X    FILE    *ff;
  1374. X    struct {
  1375. X        int             ax, bx, cx, dx, si, di, ds, es;
  1376. X    }               reg;
  1377. X
  1378. X    ff = fopen(f, "w+");    /* How else can I get a handle? */
  1379. X
  1380. X    reg.ax = 0x5701;    /* set date/time */
  1381. X    reg.bx = filehand(f);    /* file handle */
  1382. X    reg.cx = time;        /* desired time */
  1383. X    reg.dx = date;        /* desired date */
  1384. X    if (sysint21(®, ®) & 1)    /* DOS call */
  1385. X        printf("Set timestamp fail (%d)\n", reg.ax);
  1386. X    fclose(ff);
  1387. X#endif
  1388. X#if    GEMDOS
  1389. X    int    fd, set[2];
  1390. X
  1391. X    fd = Fopen(f, 0);
  1392. X    set[0] = time;
  1393. X    set[1] = date;
  1394. X    Fdatime(set, fd, 1);
  1395. X    Fclose(fd);
  1396. X#endif
  1397. X#if    UNIX
  1398. X    struct tws      tms;
  1399. X    struct timeval  tvp[2];
  1400. X    int    utimes();
  1401. X    twscopy(&tms, dtwstime());
  1402. X    tms.tw_sec = (time & 31) * 2;
  1403. X    tms.tw_min = (time >> 5) & 63;
  1404. X    tms.tw_hour = (time >> 11);
  1405. X    tms.tw_mday = date & 31;
  1406. X    tms.tw_mon = ((date >> 5) & 15) - 1;
  1407. X    tms.tw_year = (date >> 9) + 80;
  1408. X    tms.tw_clock = 0L;
  1409. X    tms.tw_flags = TW_NULL;
  1410. X    tvp[0].tv_sec = twclock(&tms);
  1411. X    tvp[1].tv_sec = tvp[0].tv_sec;
  1412. X    tvp[0].tv_usec = tvp[1].tv_usec = 0;
  1413. X    utimes(f, tvp);
  1414. X#endif
  1415. X}
  1416. X
  1417. X#if    MSDOS
  1418. Xint
  1419. Xfilehand(stream)        /* find handle on a file */
  1420. X    struct bufstr  *stream;    /* file to grab onto */
  1421. X{
  1422. X    return stream->bufhand;    /* return DOS 2.0 file handle */
  1423. X}
  1424. X#endif
  1425. X
  1426. X#if    UNIX
  1427. Xint
  1428. Xizadir(filename)        /* Is filename a directory? */
  1429. X    char           *filename;
  1430. X{
  1431. X    struct stat     buf;
  1432. X
  1433. X    if (stat(filename, &buf) != 0)
  1434. X        return (0);    /* Ignore if stat fails since */
  1435. X    else
  1436. X        return (buf.st_mode & S_IFDIR);    /* bad files trapped later */
  1437. X}
  1438. X#endif
  1439. ________This_Is_The_END________
  1440. if test `wc -c < arcdos.c` -ne     5008; then
  1441.     echo 'shar: arcdos.c was damaged during transit (should have been     5008 bytes)'
  1442. fi
  1443. fi        ; : end of overwriting check
  1444. echo 'x - arcext.c'
  1445. if test -f arcext.c; then echo 'shar: not overwriting arcext.c'; else
  1446. sed 's/^X//' << '________This_Is_The_END________' > arcext.c
  1447. X/*
  1448. X * $Header: arcext.c,v 1.5 88/06/01 19:26:31 hyc Locked $
  1449. X */
  1450. X
  1451. X/*
  1452. X * ARC - Archive utility - ARCEXT
  1453. X * 
  1454. X * Version 2.19, created on 10/24/86 at 14:53:32
  1455. X * 
  1456. X * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  1457. X * 
  1458. X * By:  Thom Henderson
  1459. X * 
  1460. X * Description: This file contains the routines used to extract files from an
  1461. X * archive.
  1462. X * 
  1463. X * Language: Computer Innovations Optimizing C86
  1464. X */
  1465. X#include <stdio.h>
  1466. X#include "arc.h"
  1467. X#if    !MSDOS
  1468. X#include <ctype.h>
  1469. X#endif
  1470. X
  1471. Xvoid    openarc(), closearc(), setstamp();
  1472. Xint    free(), match(), readhdr(), unpack();
  1473. Xchar    *strcpy(), *strcat();
  1474. X
  1475. Xvoid
  1476. Xextarc(num, arg, prt)        /* extract files from archive */
  1477. X    int             num;    /* number of arguments */
  1478. X    char           *arg[];    /* pointers to arguments */
  1479. X    int             prt;        /* true if printing */
  1480. X{
  1481. X    struct heads    hdr;    /* file header */
  1482. X    int             save;    /* true to save current file */
  1483. X    int             did[MAXARG];/* true when argument was used */
  1484. X    char           *i, *rindex();    /* string index */
  1485. X    char          **name, *malloc();    /* name pointer list,
  1486. X                         * allocator */
  1487. X    int             n;    /* index */
  1488. X    void            extfile();
  1489. X
  1490. X    name = (char **) malloc(num * sizeof(char *));    /* get storage for name
  1491. X                             * pointers */
  1492. X
  1493. X    for (n = 0; n < num; n++) {    /* for each argument */
  1494. X        did[n] = 0;    /* reset usage flag */
  1495. X#if    !MTS
  1496. X        if (!(i = rindex(arg[n], '\\')))    /* find start of name */
  1497. X            if (!(i = rindex(arg[n], '/')))
  1498. X                if (!(i = rindex(arg[n], ':')))
  1499. X                    i = arg[n] - 1;
  1500. X#else
  1501. X        if (!(i = rindex(arg[n], sepchr[0])))
  1502. X            if (arg[n][0] != tmpchr[0])
  1503. X                i = arg[n] - 1;
  1504. X            else
  1505. X                i = arg[n];
  1506. X#endif
  1507. X        name[n] = i + 1;
  1508. X    }
  1509. X
  1510. X
  1511. X    openarc(0);        /* open archive for reading */
  1512. X
  1513. X    if (num) {        /* if files were named */
  1514. X        while (readhdr(&hdr, arc)) {    /* while more files to check */
  1515. X            save = 0;    /* reset save flag */
  1516. X            for (n = 0; n < num; n++) {    /* for each template
  1517. X                             * given */
  1518. X                if (match(hdr.name, name[n])) {
  1519. X                    save = 1;    /* turn on save flag */
  1520. X                    did[n] = 1;    /* turn on usage flag */
  1521. X                    break;    /* stop looking */
  1522. X                }
  1523. X            }
  1524. X
  1525. X            if (save)    /* extract if desired, else skip */
  1526. X                extfile(&hdr, arg[n], prt);
  1527. X            else
  1528. X                fseek(arc, hdr.size, 1);
  1529. X        }
  1530. X    } else
  1531. X        while (readhdr(&hdr, arc))    /* else extract all files */
  1532. X            extfile(&hdr, "", prt);
  1533. X
  1534. X    closearc(0);        /* close archive after reading */
  1535. X
  1536. X    if (note) {
  1537. X        for (n = 0; n < num; n++) {    /* report unused args */
  1538. X            if (!did[n]) {
  1539. X                printf("File not found: %s\n", arg[n]);
  1540. X                nerrs++;
  1541. X            }
  1542. X        }
  1543. X    }
  1544. X    free(name);
  1545. X}
  1546. X
  1547. Xvoid
  1548. Xextfile(hdr, path, prt)        /* extract a file */
  1549. X    struct heads   *hdr;    /* pointer to header data */
  1550. X    char           *path;    /* pointer to path name */
  1551. X    int             prt;    /* true if printing */
  1552. X{
  1553. X    FILE           *f, *fopen();    /* extracted file, opener */
  1554. X    char            buf[STRLEN];    /* input buffer */
  1555. X    char            fix[STRLEN];    /* fixed name buffer */
  1556. X    char           *i, *rindex();    /* string index */
  1557. X
  1558. X    if (prt) {        /* printing is much easier */
  1559. X        unpack(arc, stdout, hdr);    /* unpack file from archive */
  1560. X        printf("\f");    /* eject the form */
  1561. X        return;        /* see? I told you! */
  1562. X    }
  1563. X    strcpy(fix, path);    /* note path name template */
  1564. X#if    !MTS
  1565. X    if (*path) {
  1566. X    if (!(i = rindex(fix, '\\')))    /* find start of name */
  1567. X        if (!(i = rindex(fix, '/')))
  1568. X            if (!(i = rindex(fix, ':')))
  1569. X                i = fix - 1;
  1570. X    } else i = fix -1;
  1571. X#else
  1572. X    if (!(i = rindex(fix, sepchr[0])))
  1573. X        if (fix[0] != tmpchr[0])
  1574. X            i = fix - 1;
  1575. X        else
  1576. X            i = fix;
  1577. X#endif
  1578. X    strcpy(i + 1, hdr->name);    /* replace template with name */
  1579. X
  1580. X    if (note)
  1581. X        printf("Extracting file: %s\n", fix);
  1582. X
  1583. X    if (warn && !overlay) {
  1584. X        if (f = fopen(fix, "r")) {    /* see if it exists */
  1585. X                fclose(f);
  1586. X                printf("WARNING: File %s already exists!", fix);
  1587. X                fflush(stdout);
  1588. X                while (1) {
  1589. X                    printf("  Overwrite it (y/n)? ");
  1590. X                    fflush(stdout);
  1591. X                    fgets(buf, STRLEN, stdin);
  1592. X                    *buf = toupper(*buf);
  1593. X                    if (*buf == 'Y' || *buf == 'N')
  1594. X                        break;
  1595. X                }
  1596. X                if (*buf == 'N') {
  1597. X                    printf("%s not extracted.\n", fix);
  1598. X                    fseek(arc, hdr->size, 1);
  1599. X                    return;
  1600. X                }
  1601. X        }
  1602. X    }
  1603. X#if    !MTS
  1604. X    if (!(f = fopen(fix, "wb")))
  1605. X#else
  1606. X    {
  1607. X        fortran         create();
  1608. X        void        memset();
  1609. X        char            c_name[256];
  1610. X        struct crsize {
  1611. X            short           maxsize, cursize;
  1612. X        }               c_size;
  1613. X        char            c_vol[6];
  1614. X        int             c_type;
  1615. X        strcpy(c_name, fix);
  1616. X        strcat(c_name, " ");
  1617. X        c_size.maxsize = 0;
  1618. X        c_size.cursize = hdr->length / 4096 + 1;
  1619. X        memset(c_vol, 0, sizeof(c_vol));
  1620. X        c_type = 0x100;
  1621. X        create(c_name, &c_size, c_vol, &c_type);
  1622. X    }
  1623. X    if (image) {
  1624. X        f = fopen(fix, "wb");
  1625. X    } else
  1626. X        f = fopen(fix, "w");
  1627. X    if (!f)
  1628. X#endif
  1629. X    {
  1630. X        if (warn) {
  1631. X            printf("Cannot create %s\n", fix);
  1632. X            nerrs++;
  1633. X        }
  1634. X        fseek(arc, hdr->size, 1);
  1635. X        return;
  1636. X    }
  1637. X    /* now unpack the file */
  1638. X
  1639. X    unpack(arc, f, hdr);    /* unpack file from archive */
  1640. X    fclose(f);        /* all done writing to file */
  1641. X#if    !MTS
  1642. X    setstamp(fix, hdr->date, hdr->time);    /* use filename for stamp */
  1643. X#endif
  1644. X}
  1645. ________This_Is_The_END________
  1646. if test `wc -c < arcext.c` -ne     4898; then
  1647.     echo 'shar: arcext.c was damaged during transit (should have been     4898 bytes)'
  1648. fi
  1649. fi        ; : end of overwriting check
  1650. echo 'x - arcio.c'
  1651. if test -f arcio.c; then echo 'shar: not overwriting arcio.c'; else
  1652. sed 's/^X//' << '________This_Is_The_END________' > arcio.c
  1653. X/*
  1654. X * $Header: arcio.c,v 1.7 88/06/02 16:27:32 hyc Locked $
  1655. X */
  1656. X
  1657. X/*  ARC - Archive utility - ARCIO
  1658. X
  1659. X    Version 2.50, created on 04/22/87 at 13:25:20
  1660. X
  1661. X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  1662. X
  1663. X    By:     Thom Henderson
  1664. X
  1665. X    Description:
  1666. X     This file contains the file I/O routines used to manipulate
  1667. X     an archive.
  1668. X
  1669. X    Language:
  1670. X     Computer Innovations Optimizing C86
  1671. X*/
  1672. X#include <stdio.h>
  1673. X#include "arc.h"
  1674. X#if    MTS
  1675. X#include <ctype.h>
  1676. X#endif
  1677. X
  1678. Xvoid    abort();
  1679. Xint    strlen(), free();
  1680. X
  1681. Xint
  1682. Xreadhdr(hdr, f)            /* read a header from an archive */
  1683. X    struct heads   *hdr;    /* storage for header */
  1684. X    FILE           *f;    /* archive to read header from */
  1685. X{
  1686. X#if    !MSDOS
  1687. X    unsigned char   dummy[28];
  1688. X    int             i;
  1689. X#endif
  1690. X    char            name[FNLEN];    /* filename buffer */
  1691. X    int             try = 0;/* retry counter */
  1692. X    static int      first = 1;    /* true only on first read */
  1693. X
  1694. X    if (!f)            /* if archive didn't open */
  1695. X        return 0;    /* then pretend it's the end */
  1696. X    if (feof(f))        /* if no more data */
  1697. X        return 0;    /* then signal end of archive */
  1698. X
  1699. X    if (fgetc(f) != ARCMARK) {    /* check archive validity */
  1700. X        if (warn) {
  1701. X            printf("An entry in %s has a bad header.", arcname);
  1702. X            nerrs++;
  1703. X        }
  1704. X        while (!feof(f)) {
  1705. X            try++;
  1706. X            if (fgetc(f) == ARCMARK) {
  1707. X                ungetc(hdrver = fgetc(f), f);
  1708. X                if (!(hdrver & 0x80) && hdrver <= ARCVER)
  1709. X                    break;
  1710. X            }
  1711. X        }
  1712. X
  1713. X        if (feof(f) && first)
  1714. X            abort("%s is not an archive", arcname);
  1715. X
  1716. X        if (changing && warn)
  1717. X            abort("%s is corrupted -- changes disallowed", arcname);
  1718. X
  1719. X        if (warn)
  1720. X            printf("  %d bytes skipped.\n", try);
  1721. X
  1722. X        if (feof(f))
  1723. X            return 0;
  1724. X    }
  1725. X    hdrver = fgetc(f);    /* get header version */
  1726. X    if (hdrver & 0x80)    /* sign bit? negative? */
  1727. X        abort("Invalid header in archive %s", arcname);
  1728. X    if (hdrver == 0)
  1729. X        return 0;    /* note our end of archive marker */
  1730. X    if (hdrver > ARCVER) {
  1731. X        fread(name, sizeof(char), FNLEN, f);
  1732. X#if    MTS
  1733. X        atoe(name, strlen(name));
  1734. X#endif
  1735. X        printf("I don't know how to handle file %s in archive %s\n",
  1736. X               name, arcname);
  1737. X        printf("I think you need a newer version of ARC.\n");
  1738. X        exit(1);
  1739. X    }
  1740. X    /* amount to read depends on header type */
  1741. X
  1742. X    if (hdrver == 1) {    /* old style is shorter */
  1743. X        fread(hdr, sizeof(struct heads) - sizeof(long int), 1, f);
  1744. X        hdrver = 2;    /* convert header to new format */
  1745. X        hdr->length = hdr->size;    /* size is same when not
  1746. X                         * packed */
  1747. X    } else
  1748. X#if    MSDOS
  1749. X        fread(hdr, sizeof(struct heads), 1, f);
  1750. X#else
  1751. X        fread(dummy, 27, 1, f);
  1752. X
  1753. X    for (i = 0; i < FNLEN; hdr->name[i] = dummy[i], i++);
  1754. X#if    MTS
  1755. X    (void) atoe(hdr->name, strlen(hdr->name));
  1756. X#endif
  1757. X    for (i = 0; i<4; hdr->size<<=8, hdr->size += dummy[16-i], i++);
  1758. X    hdr->date = (short) ((dummy[18] << 8) + dummy[17]);
  1759. X    hdr->time = (short) ((dummy[20] << 8) + dummy[19]);
  1760. X    hdr->crc = (short) ((dummy[22] << 8) + dummy[21]);
  1761. X    for (i = 0; i<4; hdr->length<<=8, hdr->length += dummy[26-i], i++);
  1762. X#endif
  1763. X
  1764. X    if (hdr->date > olddate
  1765. X        || (hdr->date == olddate && hdr->time > oldtime)) {
  1766. X        olddate = hdr->date;
  1767. X        oldtime = hdr->time;
  1768. X    }
  1769. X    first = 0;
  1770. X    return 1;        /* we read something */
  1771. X}
  1772. X
  1773. Xvoid
  1774. Xput_int(number, f)        /* write a 2 byte integer */
  1775. X    short           number;
  1776. X    FILE           *f;
  1777. X{
  1778. X    fputc((char) (number & 255), f);
  1779. X    fputc((char) (number >> 8), f);
  1780. X}
  1781. X
  1782. Xvoid
  1783. Xput_long(number, f)        /* write a 4 byte integer */
  1784. X    long            number;
  1785. X    FILE           *f;
  1786. X{
  1787. X    put_int((short) (number & 0xFFFF), f);
  1788. X    put_int((short) (number >> 16), f);
  1789. X}
  1790. X
  1791. Xvoid
  1792. Xwritehdr(hdr, f)        /* write a header to an archive */
  1793. X    struct heads   *hdr;    /* header to write */
  1794. X    FILE           *f;    /* archive to write to */
  1795. X{
  1796. X    fputc(ARCMARK, f);        /* write out the mark of ARC */
  1797. X    fputc(hdrver, f);    /* write out the header version */
  1798. X    if (!hdrver)        /* if that's the end */
  1799. X        return;        /* then write no more */
  1800. X#if    MSDOS
  1801. X    fwrite(hdr, sizeof(struct heads), 1, f);
  1802. X#else
  1803. X    /* byte/word ordering hassles... */
  1804. X#if    MTS
  1805. X    etoa(hdr->name, strlen(hdr->name));
  1806. X#endif
  1807. X    fwrite(hdr->name, 1, FNLEN, f);
  1808. X    put_long(hdr->size, f);
  1809. X    put_int(hdr->date, f);
  1810. X    put_int(hdr->time, f);
  1811. X    put_int(hdr->crc, f);
  1812. X    put_long(hdr->length, f);
  1813. X#endif
  1814. X
  1815. X    /* note the newest file for updating the archive timestamp */
  1816. X
  1817. X    if (hdr->date > arcdate
  1818. X        || (hdr->date == arcdate && hdr->time > arctime)) {
  1819. X        arcdate = hdr->date;
  1820. X        arctime = hdr->time;
  1821. X    }
  1822. X}
  1823. X
  1824. Xvoid
  1825. Xputc_tst(c, t)            /* put a character, with tests */
  1826. X    char            c;    /* character to output */
  1827. X    FILE           *t;    /* file to write to */
  1828. X{
  1829. X    c &= 0xff;
  1830. X    if (t)
  1831. X#if    UNIX
  1832. X        fputc(c, t);
  1833. X#else
  1834. X        if (fputc(c, t) == EOF)
  1835. X            abort("Write fail (disk full?)");
  1836. X#endif
  1837. X}
  1838. X
  1839. X/*
  1840. X * NOTE:  The filecopy() function is used to move large numbers of bytes from
  1841. X * one file to another.  This particular version has been modified to improve
  1842. X * performance in Computer Innovations C86 version 2.3 in the small memory
  1843. X * model.  It may not work as expected with other compilers or libraries, or
  1844. X * indeed with different versions of the CI-C86 compiler and library, or with
  1845. X * the same version in a different memory model.
  1846. X * 
  1847. X * The following is a functional equivalent to the filecopy() routine that
  1848. X * should work properly on any system using any compiler, albeit at the cost
  1849. X * of reduced performance:
  1850. X * 
  1851. X * filecopy(f,t,size) 
  1852. X *      FILE *f, *t; long size; 
  1853. X * { 
  1854. X *      while(size--)
  1855. X *              putc_tst(fgetc(f),t); 
  1856. X * }
  1857. X */
  1858. X#if    MSDOS
  1859. X#include <fileio2.h>
  1860. X
  1861. Xfilecopy(f, t, size)        /* bulk file copier */
  1862. X    FILE           *f, *t;    /* files from and to */
  1863. X    long            size;    /* bytes to copy */
  1864. X{
  1865. X    char           *buf;    /* buffer pointer */
  1866. X    char           *alloc();/* buffer allocator */
  1867. X    unsigned int    bufl;    /* buffer length */
  1868. X    unsigned int    coreleft();    /* space available reporter */
  1869. X    unsigned int    cpy;    /* bytes being copied */
  1870. X    long            floc, tloc, fseek();    /* file pointers, setter */
  1871. X    struct regval   reg;    /* registers for DOS calls */
  1872. X
  1873. X    if ((bufl = coreleft()) < 1000)    /* see how much space we have */
  1874. X        abort("Out of memory");
  1875. X    bufl -= 1000;        /* fudge factor for overhead */
  1876. X    if (bufl > 60000)
  1877. X        bufl = 60000;    /* avoid choking alloc() */
  1878. X    if (bufl > size)
  1879. X        bufl = size;    /* avoid wasting space */
  1880. X    buf = alloc(bufl);    /* allocate our buffer */
  1881. X
  1882. X    floc = fseek(f, 0L, 1);    /* reset I/O system */
  1883. X    tloc = fseek(t, 0L, 1);
  1884. X
  1885. X    segread(®.si);    /* set segment registers for DOS */
  1886. X
  1887. X    while (size > 0) {    /* while more to copy */
  1888. X        reg.ax = 0x3F00;/* read from handle */
  1889. X        reg.bx = filehand(f);
  1890. X        reg.cx = bufl < size ? bufl : size;    /* amount to read */
  1891. X        reg.dx = buf;
  1892. X        if (sysint21(®, ®) & 1)
  1893. X            abort("Read fail");
  1894. X
  1895. X        cpy = reg.ax;    /* amount actually read */
  1896. X        reg.ax = 0x4000;/* write to handle */
  1897. X        reg.bx = filehand(t);
  1898. X        reg.cx = cpy;
  1899. X        reg.dx = buf;
  1900. X        sysint21(®, ®);
  1901. X
  1902. X        if (reg.ax != cpy)
  1903. X            abort("Write fail (disk full?)");
  1904. X
  1905. X        size -= (long) cpy;
  1906. X    }
  1907. X
  1908. X    free(buf);        /* all done with buffer */
  1909. X}
  1910. X#else
  1911. X
  1912. Xvoid
  1913. Xfilecopy(f, t, size)        /* bulk file copier */
  1914. X    FILE           *f, *t;    /* files from and to */
  1915. X    long            size;    /* bytes to copy */
  1916. X{
  1917. X    char           *buf;    /* buffer pointer */
  1918. X    char           *malloc();    /* buffer allocator */
  1919. X    unsigned int    bufl;    /* buffer length */
  1920. X    unsigned int    cpy;    /* bytes being copied */
  1921. X
  1922. X    bufl = 32760;
  1923. X    if (bufl > size)
  1924. X        bufl = size;    /* don't waste space */
  1925. X
  1926. X    buf = malloc(bufl);
  1927. X
  1928. X    while (size > 0) {
  1929. X        cpy = fread(buf, sizeof(char),
  1930. X            bufl < size ? bufl : (unsigned short) size, f);
  1931. X        if (fwrite(buf, sizeof(char), cpy, t) != cpy)
  1932. X            abort("Write fail (no space?)");
  1933. X        size -= cpy;
  1934. X    }
  1935. X
  1936. X    free(buf);
  1937. X}
  1938. X#endif
  1939. ________This_Is_The_END________
  1940. if test `wc -c < arcio.c` -ne     7418; then
  1941.     echo 'shar: arcio.c was damaged during transit (should have been     7418 bytes)'
  1942. fi
  1943. fi        ; : end of overwriting check
  1944. echo 'x - arclst.c'
  1945. if test -f arclst.c; then echo 'shar: not overwriting arclst.c'; else
  1946. sed 's/^X//' << '________This_Is_The_END________' > arclst.c
  1947. X/*
  1948. X * $Header: arclst.c,v 1.5 88/06/01 18:05:57 hyc Locked $
  1949. X */
  1950. X
  1951. X/*  ARC - Archive utility - ARCLST
  1952. X  
  1953. X    Version 2.39, created on 04/22/87 at 13:48:29
  1954. X  
  1955. X(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  1956. X  
  1957. X    By:     Thom Henderson
  1958. X  
  1959. X    Description:
  1960. X     This file contains the routines used to list the contents
  1961. X     of an archive.
  1962. X  
  1963. X    Language:
  1964. X     Computer Innovations Optimizing C86
  1965. X*/
  1966. X#include <stdio.h>
  1967. X#include "arc.h"
  1968. X
  1969. Xvoid            rempath(), openarc(), closearc();
  1970. Xint             readhdr(), match();
  1971. X
  1972. Xvoid
  1973. Xlstarc(num, arg)        /* list files in archive */
  1974. X    int             num;    /* number of arguments */
  1975. X    char           *arg[];    /* pointers to arguments */
  1976. X{
  1977. X    struct heads    hdr;    /* header data */
  1978. X    int             list;    /* true to list a file */
  1979. X    int             did[MAXARG];    /* true when argument was used */
  1980. X    long            tnum, tlen, tsize;    /* totals */
  1981. X    int             n;    /* index */
  1982. X    void            lstfile();
  1983. X
  1984. X    tnum = tlen = tsize = 0;/* reset totals */
  1985. X
  1986. X    for (n = 0; n < num; n++)    /* for each argument */
  1987. X        did[n] = 0;    /* reset usage flag */
  1988. X    rempath(num, arg);    /* strip off paths */
  1989. X
  1990. X    if (note && !kludge) {
  1991. X        printf("Name          Length  ");
  1992. X        if (bose)
  1993. X            printf("  Stowage    SF   Size now");
  1994. X        printf("  Date     ");
  1995. X        if (bose)
  1996. X            printf("  Time    CRC");
  1997. X        printf("\n");
  1998. X
  1999. X        printf("============  ========");
  2000. X        if (bose)
  2001. X            printf("  ========  ====  ========");
  2002. X        printf("  =========");
  2003. X        if (bose)
  2004. X            printf("  ======  ====");
  2005. X        printf("\n");
  2006. X    }
  2007. X    openarc(0);        /* open archive for reading */
  2008. X
  2009. X    if (num) {        /* if files were named */
  2010. X        while (readhdr(&hdr, arc)) {    /* process all archive files */
  2011. X            list = 0;    /* reset list flag */
  2012. X            for (n = 0; n < num; n++) {    /* for each template
  2013. X                             * given */
  2014. X                if (match(hdr.name, arg[n])) {
  2015. X                    list = 1;    /* turn on list flag */
  2016. X                    did[n] = 1;    /* turn on usage flag */
  2017. X                    break;    /* stop looking */
  2018. X                }
  2019. X            }
  2020. X
  2021. X            if (list) {    /* if this file is wanted */
  2022. X                if (!kludge)
  2023. X                    lstfile(&hdr);    /* then tell about it */
  2024. X                tnum++;    /* update totals */
  2025. X                tlen += hdr.length;
  2026. X                tsize += hdr.size;
  2027. X            }
  2028. X            fseek(arc, hdr.size, 1);    /* move to next header */
  2029. X        }
  2030. X    } else
  2031. X        while (readhdr(&hdr, arc)) {    /* else report on all files */
  2032. X            if (!kludge)
  2033. X                lstfile(&hdr);
  2034. X            tnum++;    /* update totals */
  2035. X            tlen += hdr.length;
  2036. X            tsize += hdr.size;
  2037. X            fseek(arc, hdr.size, 1);    /* skip to next header */
  2038. X        }
  2039. X
  2040. X    closearc(0);        /* close archive after reading */
  2041. X
  2042. X    if (note && !kludge) {
  2043. X        printf("        ====  ========");
  2044. X        if (bose)
  2045. X            printf("            ====  ========");
  2046. X        printf("\n");
  2047. X    }
  2048. X    if (note) {
  2049. X        printf("Total %6ld  %8ld", tnum, tlen);
  2050. X        if (bose) {
  2051. X            if (tlen)
  2052. X                printf("            %3ld%%", 100L - (100L * tsize) / tlen);
  2053. X            else
  2054. X                printf("            ---");
  2055. X            printf("  %8ld", tsize);
  2056. X        }
  2057. X        printf("\n");
  2058. X
  2059. X        for (n = 0; n < num; n++) {    /* report unused args */
  2060. X            if (!did[n]) {
  2061. X                printf("File not found: %s\n", arg[n]);
  2062. X                nerrs++;
  2063. X            }
  2064. X        }
  2065. X    }
  2066. X}
  2067. X
  2068. Xvoid
  2069. Xlstfile(hdr)            /* tell about a file */
  2070. X    struct heads   *hdr;    /* pointer to header data */
  2071. X{
  2072. X    int             yr, mo, dy;    /* parts of a date */
  2073. X    int             hh, mm;    /* parts of a time */
  2074. X
  2075. X    static char    *mon[] =    /* month abbreviations */
  2076. X    {
  2077. X     "Jan", "Feb", "Mar", "Apr",
  2078. X     "May", "Jun", "Jul", "Aug",
  2079. X     "Sep", "Oct", "Nov", "Dec"
  2080. X    };
  2081. X
  2082. X    if (!note) {        /* no notes means short listing */
  2083. X        printf("%s\n", hdr->name);
  2084. X        return;
  2085. X    }
  2086. X
  2087. X    yr = (hdr->date >> 9) & 0x7f;    /* dissect the date */
  2088. X    mo = (hdr->date >> 5) & 0x0f;
  2089. X    dy = hdr->date & 0x1f;
  2090. X
  2091. X    hh = (hdr->time >> 11) & 0x1f;    /* dissect the time */
  2092. X    mm = (hdr->time >> 5) & 0x3f;
  2093. X/*    ss = (hdr->time & 0x1f) * 2;    seconds, not used. */
  2094. X
  2095. X    printf("%-12s  %8ld  ", hdr->name, hdr->length);
  2096. X
  2097. X    if (bose) {
  2098. X        switch (hdrver) {
  2099. X        case 1:
  2100. X        case 2:
  2101. X            printf("   --   ");
  2102. X            break;
  2103. X        case 3:
  2104. X            printf(" Packed ");
  2105. X            break;
  2106. X        case 4:
  2107. X            printf("Squeezed");
  2108. X            break;
  2109. X        case 5:
  2110. X        case 6:
  2111. X        case 7:
  2112. X            printf("crunched");
  2113. X            break;
  2114. X        case 8:
  2115. X            printf("Crunched");
  2116. X            break;
  2117. X        case 9:
  2118. X            printf("Squashed");
  2119. X            break;
  2120. X        default:
  2121. X            printf("Unknown!");
  2122. X        }
  2123. X
  2124. X        if (hdr->length)
  2125. X            printf("  %3ld%%", 100L - (100L * hdr->size) / hdr->length);
  2126. X        else
  2127. X            printf("  ---");
  2128. X        printf("  %8ld  ", hdr->size);
  2129. X    }
  2130. X    printf("%2d %3s %02d", dy, mon[mo - 1], (yr + 80) % 100);
  2131. X
  2132. X    if (bose)
  2133. X        printf("  %2d:%02d%c  %04x",
  2134. X               (hh > 12 ? hh - 12 : hh), mm, (hh > 11 ? 'p' : 'a'),
  2135. X               hdr->crc & 0xffff);
  2136. X
  2137. X    printf("\n");
  2138. X}
  2139. ________This_Is_The_END________
  2140. if test `wc -c < arclst.c` -ne     4418; then
  2141.     echo 'shar: arclst.c was damaged during transit (should have been     4418 bytes)'
  2142. fi
  2143. fi        ; : end of overwriting check
  2144. exit 0
  2145.  
  2146. -- 
  2147. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  2148.  
  2149.  
  2150.